import asyncio
import sys

import qasync
from PySide6.QtCore import QAbstractNativeEventFilter
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQuick import QQuickWindow, QSGRendererInterface

from src.utils.repair.Windows import WindowsEventFilter, WindowEffect
from src.common.signal_bus import SignalBus


class MGui:
    def __init__(self, event_filter: QAbstractNativeEventFilter = None, context=None):

        if context is None:
            context = {}
        # 初始化
        self.app = QGuiApplication(sys.argv)
        from src.common.qta_icon_font import QtAwesomIconFont  # noqa
        QQuickWindow.setGraphicsApi(QSGRendererInterface.GraphicsApi.OpenGL)
        self.engine = QQmlApplicationEngine()
        self.app.aboutToQuit.connect(self.engine.deleteLater)
        self.signal_bus = SignalBus()
        self.engine.quit.connect(self.signal_bus.closeApp)
        self.app.aboutToQuit.connect(self.signal_bus.closeApp)
        self.engine.quit.connect(self.app.quit)
        self.event_loop = qasync.QEventLoop(self.app)

        asyncio.set_event_loop(self.event_loop)
        self.app_close_event = asyncio.Event()
        self.app.aboutToQuit.connect(self.app_close_event.set)
        self.engine.quit.connect(self.app_close_event.set)

        self.wef = WindowsEventFilter(2)
        self.app.installNativeEventFilter(self.wef)
        if event_filter:
            self.app.installNativeEventFilter(event_filter)
        if context:
            root = self.engine.rootContext()
            for k, v in context.items():
                root.setContextProperty(k, v)
        self.win_rep = WindowEffect()

    def start(self, root, moudle="Gui"):
        # 加载qml文件
        self.engine.addImportPath(root)
        self.engine.loadFromModule(moudle, "Main")
        self._on_load_after()
        if not self.engine.rootObjects():
            sys.exit(-1)
        with self.event_loop:
            self.event_loop.run_until_complete(self.app_close_event.wait())

    def _on_load_after(self):
        # windows 恢复特效
        if sys.platform == 'win32':
            for win in self.app.allWindows():
                self.win_rep.addShadowEffect(win.winId())
                self.win_rep.addWindowAnimation(win.winId())
                self.win_rep.setAcrylicEffect(win.winId())
